"""
Case Type   : 功能测试
Case Name   : 参数max_concurrent_autonomous_transactions值正常生效
Create At   : 2024/7/3
Owner       : peilinqian
Description :
    step1:设置max_concurrent_autonomous_transactions参数值为0;
    step2:创建表;
    step3:执行自治事务
    step4:设置max_concurrent_autonomous_transactions参数值为5;
    step4:6个并发执行自治事务;
Expect      :
    step1:设置max_concurrent_autonomous_transactions参数值为0; expect：设置成功
    step2:创建表; expect：设置成功
    step3:执行自治事务 expect：执行失败
    step4:设置max_concurrent_autonomous_transactions参数值为5; expect：设置成功
    step4:6个并发执行自治事务; expect：5个成功，1个失败
History     :
"""
import os
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class DblinkCase(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)}:初始化----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.log.info('----查询参数----')
        self.init_para = self.com.show_param(
            "max_concurrent_autonomous_transactions")
        self.t_name = 't_autonomous_transaction_0035'

    def test_main(self):
        step_txt = '----step1:设置max_concurrent_autonomous_transactions' \
                   '参数值为0; expect：设置成功----'
        self.log.info(step_txt)
        msg = self.pri_sh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f"max_concurrent_autonomous_transactions=0", )
        self.assertTrue(msg, '执行失败:' + step_txt)
        self.restart_result = self.pri_sh.restart_db_cluster()
        self.log.info('----查询参数----')
        self.com.show_param("max_concurrent_autonomous_transactions")

        step_txt = '----step2:创建表; expect：设置成功----'
        self.log.info(step_txt)
        sql = f"drop table if exists {self.t_name};" \
              f"create table {self.t_name} (a int,b int);"
        msg = self.pri_sh.execut_db_sql(sql)
        self.log.info(msg)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, msg,
                      '执行失败:' + step_txt)

        step_txt = '----step3:执行自治事务 expect：执行失败----; '
        self.log.info(step_txt)
        sql = f'''start transaction;
        declare
            pragma autonomous_transaction;
        begin
            insert into {self.t_name} values(3,3);
            perform pg_sleep(3);
        end;
        insert into {self.t_name} values(1,5);
        rollback;
        select * from {self.t_name};'''
        msg = self.pri_sh.execut_db_sql(sql)
        self.log.info(msg)
        err_flag = 'ERROR:  concurrent autonomous transactions ' \
                   'reach its maximun : 0'
        self.assertIn(err_flag, msg, '执行失败:' + step_txt)

        step_txt = '----step4:设置max_concurrent_autonomous_transactions' \
                   '参数值为5; expect：设置成功----'
        self.log.info(step_txt)
        msg = self.pri_sh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f"max_concurrent_autonomous_transactions=5", )
        self.assertTrue(msg, '执行失败:' + step_txt)
        self.restart_result = self.pri_sh.restart_db_cluster()
        self.log.info('----查询参数----')
        self.com.show_param("max_concurrent_autonomous_transactions")

        step_txt = '----step5:6个并发执行自治事务; expect：5个成功，1个失败----'
        self.log.info(step_txt)
        session = []
        session_result = []
        for index in range(6):
            session.append(ComThread(self.pri_sh.execut_db_sql,
                                     args=(sql,)))
            session[index].setDaemon(True)
            session[index].start()
        for index in range(6):
            session[index].join()
            session_result.append(session[index].get_result())
        self.log.info(session_result)
        ok_list = [item for item in session_result if
                   'row' in item]
        err_flag = 'ERROR:  concurrent autonomous transactions ' \
                   'reach its maximun : 5'
        err_list = [item for item in session_result if
                    err_flag in item]
        self.assertEqual(5, len(ok_list), '执行失败:' + step_txt)
        self.assertEqual(1, len(err_list), '执行失败:' + step_txt)

    def tearDown(self):
        self.log.info('----this is tearDown----')
        step_txt = '----删除表，恢复参数; expect：成功----'
        self.log.info(step_txt)
        sql = f"drop table if exists {self.t_name};"
        msg1 = self.pri_sh.execut_db_sql(sql)
        msg2 = self.pri_sh.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f"max_concurrent_autonomous_transactions={self.init_para}", )
        self.restart_result = self.pri_sh.restart_db_cluster()
        self.log.info('----查询参数----')
        msg3 = self.com.show_param("max_concurrent_autonomous_transactions")

        self.log.info(f'----{os.path.basename(__file__)}:执行完毕----')
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, msg1,
                      '执行失败:' + step_txt)
        self.assertTrue(msg2, '执行失败:' + step_txt)
        self.assertEqual(msg3, self.init_para, '执行失败:' + step_txt)
